package com.tako.utils;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/**
 * @author zhangyu
 * @date 2023/1/15
 */
public class GZIPUtil {


    /**
     * 使用gzip压缩字符串
     *
     * @param str 要压缩的字符串
     * @return
     */
    public static String compress(String str) throws IOException {
        byte[] bytes = compressToBytes(str);
        return new BASE64Encoder().encode(bytes);
    }

    public static byte[] compressToBytes(String str) throws IOException {
        if (str == null || str.length() == 0) {
            return null;
        }
        ByteArrayOutputStream out = null;
        GZIPOutputStream gzip = null;
        try {
            out = new ByteArrayOutputStream();
            gzip = new GZIPOutputStream(out);
            gzip.write(str.getBytes());
        } finally {
            if (gzip != null) {
                gzip.close();
            }
            if (out != null) {
                out.close();
            }
        }
        return out.toByteArray();
    }

    /**
     * 使用gzip解压缩
     *
     * @param compressedStr 压缩字符串
     * @return
     */
    public static String uncompress(String compressedStr) throws IOException {
        if (compressedStr == null) {
            return null;
        }

        byte[] compressed = new BASE64Decoder().decodeBuffer(compressedStr);

        return uncompressBytes(compressed);
    }

    public static String uncompressBytes(byte[] compressed) throws IOException {
        if (compressed == null) {
            return null;
        }

        try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
            try (
                    ByteArrayInputStream in = new ByteArrayInputStream(compressed);
                    GZIPInputStream gis = new GZIPInputStream(in)) {
                byte[] buffer = new byte[1024];
                int offset;
                while ((offset = gis.read(buffer)) != -1) {
                    out.write(buffer, 0, offset);
                }
            }
            return out.toString();
        }
    }
}
